package com.shi.desktop.indexer;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Properties;

import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

public class FileIndexer {

	protected FileHandler fileHandler;

	public FileIndexer(Properties props) throws IOException {
		fileHandler = new ExtensionFileHandler(props);
	}

	public void index(IndexWriter writer, File file)
			throws FileHandlerException {
		if (file.canRead()) {
			if (file.isDirectory()) {
				String[] files = file.list();
				if (files != null) {
					for (int i = 0; i < files.length; i++) {
						index(writer, new File(file, files[i]));
					}
				}
			} else {
				System.out.println("Indexing " + file);
				try {
					Document doc = fileHandler.getDocument(file);
					if (doc != null) {
						doc.add(new Field("path", (file.getParentFile()).getPath(), Field.Store.YES,
								Field.Index.NOT_ANALYZED));
						doc.add(new Field("modified",
						        DateTools.timeToString(file.lastModified(), DateTools.Resolution.MINUTE),
						        Field.Store.YES, Field.Index.NOT_ANALYZED));
						doc.add(new Field("filename", file.getName(), Field.Store.YES, Field.Index.ANALYZED));
						writer.addDocument(doc);
					} else {
						System.err.println("Cannot handle"
								+ file.getAbsolutePath() + "; skipping");
					}
				} catch (Exception e) {
					System.err.println("Cannot index " + file.getAbsolutePath()
							+ "; skipping (" + e.getMessage() + ")");
				}
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		if (args.length < 3) {
			usage();
			System.exit(0);
		}
		Properties props = new Properties();
		props.load(new FileInputStream(args[0]));

		Date start = new Date();
		Directory dir = FSDirectory.getDirectory(args[2]);
		IndexWriter writer = new IndexWriter(dir, new CJKAnalyzer(), true,
				IndexWriter.MaxFieldLength.LIMITED);
		FileIndexer indexer = new FileIndexer(props);
		indexer.index(writer, new File(args[1]));
		writer.optimize();
		writer.close();
		Date end = new Date();
		IndexReader reader = IndexReader.open(dir);
		System.out.println("Documents indexed: " + reader.numDocs());
		System.out.println(end.getTime() - start.getTime()
				+ " total milliseconds");
		reader.close();
	}

	private static void usage() {
		System.err.println("USAGE: java " + FileIndexer.class.getName()
				+ " /path/to/properties /path/to/file/or/directory"
				+ " /path/to/index");
	}
}
